// --------------------------------------------------------------------------------------
// JSON type provider - methods that are called from the generated erased code
// --------------------------------------------------------------------------------------
namespace FSharp.Data.Runtime.BaseTypes

open System.ComponentModel
open System.IO
open FSharp.Data

#nowarn "10001"

/// <exclude />
type IJsonDocument =
    abstract JsonValue: JsonValue

    [<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
    [<CompilerMessageAttribute("This method is intended for use in generated code only.",
                               10001,
                               IsHidden = true,
                               IsError = false)>]
    abstract Path: unit -> string

    [<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
    [<CompilerMessageAttribute("This method is intended for use in generated code only.",
                               10001,
                               IsHidden = true,
                               IsError = false)>]
    abstract CreateNew: value: JsonValue * pathIncrement: string -> IJsonDocument

/// <summary>Underlying representation of types generated by JsonProvider</summary>
/// <namespacedoc>
///   <summary>Contains the runtime base types used by generated row types for FSharp.Data type providers.</summary>
/// </namespacedoc>
[<StructuredFormatDisplay("{JsonValue}")>]
type JsonDocument =

    private
        {
            /// <exclude />
            Json: JsonValue
            /// <exclude />
            Path: string
        }

    interface IJsonDocument with
        member x.JsonValue = x.Json
        member x.Path() = x.Path

        member x.CreateNew(value, pathIncrement) =
            JsonDocument.Create(value, x.Path + pathIncrement)

    /// The underlying JsonValue
    member x.JsonValue = x.Json

    /// <exclude />
    [<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
    [<CompilerMessageAttribute("This method is intended for use in generated code only.",
                               10001,
                               IsHidden = true,
                               IsError = false)>]
    override x.ToString() = x.JsonValue.ToString()

    /// <exclude />
    [<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
    [<CompilerMessageAttribute("This method is intended for use in generated code only.",
                               10001,
                               IsHidden = true,
                               IsError = false)>]
    static member Create(value, path) =
        { Json = value; Path = path } :> IJsonDocument

    /// <exclude />
    [<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
    [<CompilerMessageAttribute("This method is intended for use in generated code only.",
                               10001,
                               IsHidden = true,
                               IsError = false)>]
    static member Create(reader: TextReader) =
        use reader = reader
        let text = reader.ReadToEnd()
        let value = JsonValue.Parse(text)
        JsonDocument.Create(value, "")

    /// <exclude />
    [<EditorBrowsableAttribute(EditorBrowsableState.Never)>]
    [<CompilerMessageAttribute("This method is intended for use in generated code only.",
                               10001,
                               IsHidden = true,
                               IsError = false)>]
    static member CreateList(reader: TextReader) =
        use reader = reader
        let text = reader.ReadToEnd()

        match JsonValue.ParseMultiple(text) |> Seq.toArray with
        | [| JsonValue.Array array |] -> array
        | array -> array
        |> Array.mapi (fun i value -> JsonDocument.Create(value, "[" + (string i) + "]"))
